package com.atguigu.gmallre.mock.stage;

import com.atguigu.mock.util.LogUtil;
import com.atguigu.gmallre.mock.bean.CouponUse;
import com.atguigu.gmallre.mock.bean.OrderInfo;
import com.atguigu.gmallre.mock.bean.PaymentInfo;

import com.atguigu.gmallre.mock.config.AppConfig;
import com.atguigu.gmallre.mock.factory.UserSession;
import com.atguigu.gmallre.mock.log.AppCommon;
import com.atguigu.gmallre.mock.log.AppDisplay;
import com.atguigu.gmallre.mock.log.AppMain;
import com.atguigu.gmallre.mock.log.AppPage;
import com.atguigu.gmallre.mock.log.enums.ItemType;
import com.atguigu.gmallre.mock.log.enums.PageId;
import com.atguigu.gmallre.mock.service.*;


import com.atguigu.mock.util.RanOpt;
import com.atguigu.mock.util.RandomBox;
import com.atguigu.mock.util.RandomNum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.UUID;

import static com.atguigu.gmallre.mock.constant.GmallConstant.*;


@Component("payment")
public class PaymentStage implements Stage {

    @Autowired
    PaymentInfoService paymentInfoService;

    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    UserInfoService userInfoService;

    @Autowired
    CouponUseService couponUseService;

    @Autowired
    OrderStatusLogService orderStatusLogService;

    @Autowired
    LogService logService;


    @Autowired
    LoginStage loginStage;

    @Override
    public boolean handle() {
        if(UserSession.getOrderInfo()==null){
            return false;
        }

        AppMain mainlog = mainlog();
        loginStage.checkLogin(mainlog);

        logService.doLog(mainlog) ;

        PaymentInfo paymentInfo = genPaymentInfo();
        paymentInfoService.saveOrUpdate(paymentInfo);

        UserSession.addTimeByDuringTime(10000);
        paymentInfo.setCallbackTime(UserSession.getCurDateTime());
        paymentInfo.setPaymentStatus(PAYMENT_STATUS_DONE);
        paymentInfo.setCallbackContent("callback xxxxxxx");
        paymentInfoService.saveOrUpdate(paymentInfo);
        updateOrderInfo();

        UserSession.setLastPageId(PageId.payment);
        return true;
    }


    private AppMain mainlog(){
        AppCommon appCommon = UserSession.getAppCommon();

        OrderInfo orderInfo = UserSession.getOrderInfo();


        Integer durTime= RandomNum.getRandInt(5000, AppConfig.page_during_max_ms);

        AppPage appPage = AppPage.builder()
                .last_page_id(UserSession.getLastPageId())
                .item(orderInfo.getId().toString())
                .item_type(ItemType.order_id)
                .during_time(durTime)
                .page_id(PageId.payment).buildFinal();


        UserSession.addTimeByDuringTime(appPage.getDuring_time());
        Long ts= UserSession.getCurDateTime().getTime();
        AppMain appMain = AppMain.builder().common(appCommon).page(appPage)  .ts(ts).build();
        return appMain;

    }


    private PaymentInfo genPaymentInfo(){
        OrderInfo orderInfo = UserSession.getOrderInfo();
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setOutTradeNo(UUID.randomUUID().toString());
        paymentInfo.setUserId(orderInfo.getUserId());

         RandomBox<String> paymentTypeBox=new RandomBox(new RanOpt(PAYMENT_TYPE_ALIPAY,AppConfig.payment_type_weight[0])
                ,new RanOpt(PAYMENT_TYPE_WECHAT,AppConfig.payment_type_weight[1]),
                new RanOpt(PAYMENT_TYPE_UNION,AppConfig.payment_type_weight[2]));
        String paymentType = paymentTypeBox.getRandStringValue();
        paymentInfo.setPaymentType(paymentType);

        paymentInfo.setPaymentStatus(PAYMENT_STATUS_TODO);
        paymentInfo.setCreateTime(UserSession.getCurDateTime());
        paymentInfo.setCallbackTime( null);
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());

        return paymentInfo;
    }

    private  void  updateOrderInfo(){
        OrderInfo orderInfo = UserSession.getOrderInfo();
        orderInfo.setOrderStatus(ORDER_STATUS_PAID);
        orderInfo.setOperateTime(UserSession.getCurDateTime());
        orderInfoService.saveOrUpdate(orderInfo);
        orderStatusLogService.genOrderStatusLog(orderInfo);
        usedCoupon(    orderInfo.getCouponUse());

    }


    public  void   usedCoupon(  CouponUse couponUse){
        if(couponUse!=null) {
            couponUse.setOperateTime(UserSession.getCurDateTime());
            couponUse.setUsedTime(UserSession.getCurDateTime());
            couponUse.setCouponStatus(COUPON_STATUS_USED);

            couponUseService.saveOrUpdate(couponUse, true);
        }
     }


}
